package de.ret_world.openrpgstudio.engine;

import com.artemis.SystemManager;
import com.artemis.World;
import de.ret_world.openrpgstudio.editor.gui.DatabaseDialog;
import de.ret_world.openrpgstudio.engine.artemis.systems.EntitySystemPlugin;
import de.ret_world.openrpgstudio.engine.artemis.systems.RenderSystem;
import de.ret_world.openrpgstudio.engine.loading.LoadPlugin;
import de.ret_world.openrpgstudio.engine.loading.LoadingLoop;
import org.apache.log4j.Logger;
import org.java.plugin.PluginLifecycleException;
import org.java.plugin.registry.Extension;
import org.java.plugin.registry.ExtensionPoint;
import org.jrabbit.base.input.KeyboardHandler;
import org.jrabbit.base.input.MouseHandler;
import org.jrabbit.base.managers.window.WindowManager;
import org.jrabbit.standard.game.main.StandardGame;
import org.jrabbit.standard.game.managers.GameManager;
import org.lwjgl.input.Keyboard;

/**
 * The main class of the engine.
 *
 * @author emu
 */
public class Game extends StandardGame {

    public Game(String title) {
        super(title);
    }

    @Override
    protected void setup() {
        World entityworld = new World();

        SystemManager sm = entityworld.getSystemManager();
        sm.setSystem(new RenderSystem());
        
        Logger.getLogger(Game.class).info("Running EntitySystemPlugins...");
        ExtensionPoint toolExtPoint = GameLauncher.manager.getRegistry().getExtensionPoint(GameLauncher.PLUGIN_ID, "EntitySystemPlugin");
        EntitySystemPlugin plugin = null;
        for (Extension ext : toolExtPoint.getConnectedExtensions()) {
            //initialize the plugin
            if (GameLauncher.manager.isPluginEnabled(ext.getDeclaringPluginDescriptor())) {
                try {
                    // Activate plug-in that declares extension.
                    GameLauncher.manager.activatePlugin(ext.getDeclaringPluginDescriptor().getId());
                    // Get plug-in class loader.
                    ClassLoader classLoader = GameLauncher.manager.getPluginClassLoader(ext.getDeclaringPluginDescriptor());
                    // Load Tool class.
                    Class<?> clazz = classLoader.loadClass(ext.getParameter("class").valueAsString());
                    // Create Tool instance.
                    plugin = (EntitySystemPlugin) clazz.newInstance();
                    // Initialize class instance according to interface contract.
                    sm.setSystem(plugin.getEntitySystem());
                    Logger.getLogger(Game.class).info("Loading EntitySystem: "+plugin.getEntitySystem().getClass().getCanonicalName());
                } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | PluginLifecycleException ex) {
                    Logger.getLogger(Game.class).error(ex);
                }
            }
        }
        
        Logger.getLogger(Game.class).info("...Done");

        sm.initializeAll();

        LoadingLoop ll = new LoadingLoop(entityworld);
        ll.run();
        
        EntityWorld eworld = new EntityWorld(entityworld);
        eworld.makeCurrent();
    }

    @Override
    public void advanceGame(int delta) {
        if (KeyboardHandler.wasKeyPressed(Keyboard.KEY_ESCAPE)) {
            exit();
        }
        if (KeyboardHandler.wasKeyPressed(Keyboard.KEY_F11)) {
            profiler.setVisible(!profiler.visible());
        }
    }

    @Override
    public void update(int delta) {
        profiler.beginLogic();
        KeyboardHandler.update();
        MouseHandler.update();
        advanceGame(delta);
        GameManager.world().update(delta);
        GameManager.soundBoard().update(delta);
        profiler.update(delta);
        profiler.endLogic();
    }

    @Override
    public void render() {
        profiler.beginRender();
        WindowManager.controller().beginRender();
        GameManager.world().render();
        profiler.render();
        WindowManager.controller().endRender();
        profiler.endRender();
    }
}
